﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace MassIntellect.WorkIt.Frames
{
    public class XmlVerify<T> : WorkFrame, IServiceLocatorDepend
        where T : IXmlVerificator, new()
    {
        private IXmlVerificator Verificator;

        public XmlVerify()
        {
            Verificator = typeof(T).CreateInstance<IXmlVerificator>();
            Verificator.Owner = this;
            _ErrorPipe = new Pipe { Name = "Error", Scope = Scope.Public };
        }

        private XElement GetContent(PulseArgs args)
        {
            string key = ContentKey.IsEmpty() ? "Content" : ContentKey;
            return args.ContainsKey(key) ?
                args[key] as XElement : null;
        }

        [Serialize(IgnoreDefault = true)]
        public string ContentKey { get; set; }

        [Serialize(IgnoreDefault = true)]
        public string SubjectKey { get; set; }

        /// <summary>
        /// Канал для ошибочных
        /// </summary>
        [Serialize]
        public string ErrorPipeName
        {
            get
            {
                return _ErrorPipe.Name;
            }
            set
            {
                _ErrorPipe.Name = value;
            }
        }
        private IPipe _ErrorPipe;

        public override IEnumerable<IPipe> Pipes
        {
            get
            {
                yield return this;
                yield return _ErrorPipe;
            }
        }

        public override IPipe this[string NameIndex]
        {
            get
            {
                IPipe pipe = base[NameIndex];
                if (pipe == Pipe.Null && NameIndex == _ErrorPipe.Name)
                    pipe = _ErrorPipe;
                return pipe;
            }
        }

        protected override void protectedPulse(PulseArgs args)
        {
            IEnumerable<string> remarks;
            if (!Verificator.Verify(GetContent(args), out remarks))
            {
                args = args.Clone();
                foreach (var item in remarks)
                    Log("{0} {1}", args[GetKeyOrDefault(SubjectKey, "Subject")], item);
                _ErrorPipe.Pulse(args);
            }
            else
                base.protectedPulse(args);
        }

        #region IServiceLocatorDepend Members

        private IServiceLocator _ServiceLocator;
        public virtual IServiceLocator ServiceLocator
        {
            get { return _ServiceLocator ?? WorkIt.ServiceLocator.NoService; }
            set { _ServiceLocator = value; }
        }

        #endregion
    }
}
